package com.omiis.wechat.performance_test2;

import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Map;

import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.socket.client.Ack;
import io.socket.client.IO;
import io.socket.client.IO.Options;
import io.socket.client.Socket;
import io.socket.emitter.Emitter.Listener;

public abstract class AbstractOmiisMessager implements IOmiisMessager {
	private static Logger logger = LoggerFactory.getLogger(AbstractOmiisMessager.class);
	private Socket socket;
	private Options opts;
	private String uri = "";
	private String host = "localhost";
	private int port = 7005;
	private String userId = "omiis-wechat";
	private ResponseMessageHandler rmh;

	// private String channelId = "WECHAT";
	// private String senderId = channelId;
	// private String senderRole = "CUSTOMER";
	private VUser vUser = null;

	@Override
	public void registerMessageListener(ResponseMessageHandler rmh) {
		this.rmh = rmh;
		vUser = ((OmiisResponseMessageHandler) rmh).getvUser();
		if (isConnected()) {
			throw new RuntimeException("已连接！");
		}
		try {
			config();
			socket = IO.socket(uri, opts);
			registerDefaultEvent();
			socket.on(this.rmh.getEvent(), this.rmh);
			rmh.setMessager(this);
		} catch (URISyntaxException e) {
			throw new RuntimeException(e.getMessage(), e);
		}
	}

	/**
	 * 连接至服务器之后，需要注册，暂时内部注册，后续是否开放视情况定夺 by 9527
	 */
	private void registerDefaultEvent() {
		socket.on(socket.EVENT_CONNECT, new Listener() {
			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_CONNECT", Arrays.toString(args));
				logger.info("连接至全媒体Server");
				BusMessage busMessage = new BusMessage();
				busMessage.setChannelId(vUser.getChannelId());
				busMessage.setMsgType("REGISTER");
				busMessage.setSenderId(vUser.getSenderId());
				busMessage.setSenderRole(vUser.getSenderRole());
				socket.emit(EVENT_OMIIS_CUSTOM_MESSAGE, new Object[] { new JSONObject(busMessage) }, new Ack() {
					@Override
					public void call(Object... args) {
						logger.info("Emit返回信息：{}", Arrays.toString(args));
					}
				});
				logger.info("申请注册全媒体Server");
			}
		}).on(socket.EVENT_DISCONNECT, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_DISCONNECT", Arrays.toString(args));
				disconnect();
				System.exit(-1);
			}
		}).on(socket.EVENT_RECONNECT, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_RECONNECT", Arrays.toString(args));
			}
		}).on(socket.EVENT_CONNECT_ERROR, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_CONNECT_ERROR", Arrays.toString(args));
			}
		}).on(socket.EVENT_CONNECT_TIMEOUT, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_CONNECT_TIMEOUT", Arrays.toString(args));
			}
		}).on(socket.EVENT_RECONNECT_FAILED, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_RECONNECT_FAILED", Arrays.toString(args));
			}
		}).on(socket.EVENT_RECONNECT_ERROR, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_RECONNECT_ERROR", Arrays.toString(args));
			}
		}).on(socket.EVENT_RECONNECT_ERROR, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_RECONNECT_ERROR", Arrays.toString(args));
			}
		}).on(socket.EVENT_MESSAGE, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_MESSAGE", Arrays.toString(args));
			}
		}).on(socket.EVENT_RECONNECTING, new Listener() {

			@Override
			public void call(Object... args) {
				logger.info("Event：{}，Msg：{}", "EVENT_RECONNECTING", Arrays.toString(args));
			}
		});
	}

	@Override
	public String connect() {
		if (isConnected()) {
			throw new RuntimeException("已连接！");
		}
		if (rmh == null) {
			throw new RuntimeException("未注册消息Listener");
		}
		socket = socket.connect();
		return "true";
	}

	private void config() {
		host = WeChatConfiguration.getIngleton().getString("OMIIS_SERVER_HOST", "localhost");
		port = WeChatConfiguration.getIngleton().getInt("OMIIS_SERVER_PORT", 7005);
		userId = WeChatConfiguration.getIngleton().getString("OMIIS_SERVER_USER_ID", "omiis-wechat");
		// host = wechatConfiguration.getString("OMIIS_SERVER_HOST",
		// "localhost");
		// port = wechatConfiguration.getInt("OMIIS_SERVER_PORT", 7005);
		// userId = wechatConfiguration.getString("OMIIS_SERVER_USER_ID",
		// "omiis-wechat");
		String param = null;
		if ("AGENT".equals(vUser.getSenderRole())) {
			param = "role=AGENT&userId=" + vUser.getSenderId() + "&password=" + vUser.getSenderId();
		} else {
			param = "role=WECHAT&userId=omiis-wechat&password=omiis-wechat";
		}
		String token = HttpRequest.sendHttpPostRequest("http://" + host + ":7003/token/request", param);
		// String token = HttpRequest.sendHttpPostRequest("http://" + host +
		// ":7003/token/request",
		// "role=WECHAT&userId=omiis-wechat&password=omiis-wechat");
		uri = "http://" + host + ":" + port + "?userId=" + userId + "&token=" + token + "&role="
				+ IPreferences.CHANNEL_ID;
		logger.info("全媒体连接地址：{}", uri);
		Options options = new Options();
		options.forceNew = true;
		options.port = port;
		options.reconnection = true;
	}

	@Override
	public boolean isConnected() {
		return socket != null && socket.connected();
	}

	@Override
	public <T> String sendMessage(T message) {
		if (!isConnected()) {
			connect();
		}
		Map<String, String> map = null;
		if (message instanceof Map) {
			map = (Map) message;
		} else {
			throw new RuntimeException("不支持的消息体！");
		}
		BusMessage bm = new BusMessage();
		bm.setSenderId(map.get("senderId"));
		bm.setMsgType(map.get("msgType"));
		bm.setChannelId(map.get("channelId"));
		bm.setConversationId(map.get("conversationId"));
		bm.setReceiverId(map.get("receiverId"));
		bm.setSenderRole(map.get("senderRole"));
		bm.setSendTime(DateUtil.getCurrentDate());
		bm.setMsgContent(map.get("msgContent"));
		JSONObject jsonObj = new JSONObject(bm);
		logger.info("发送信息至全媒体，内容：{}", jsonObj);
		socket.emit(EVENT_OMIIS_CUSTOM_MESSAGE, new Object[] { jsonObj }, new Ack() {
			@Override
			public void call(Object... args) {
				logger.info("Emit返回的信息：{}", Arrays.toString(args));
			}
		});
		logger.info("发送信息至全媒体结束。");
		return "true";
	}

	@Override
	public String disconnect() {
		if (socket == null || !socket.connected())
			return "false";
		socket.disconnect();
		return "true";
	};
}
